package com.adee.java;

import lombok.AllArgsConstructor;
import lombok.Data;

import java.io.Serializable;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;

/**
 * TypeVariable 类型变量
 * 泛型信息在编译时会被转换成一个特定的类型，而TypeVariable就是用来反映在JVM编译该泛型前的信息。（通俗的讲，TypeVariable
 * 就是我们常用的List 、Map<K,V>中的T，K这种泛型变量）。
 * 还可以对类型变量加上extends限定，这样会有类型变量对应的上限；值得注意的是，类型变量的上限可以有多个，必须使用&连接，例如：
 * List<T extends Number & Serializable>，其中&后必须是接口：
 *
 * public interface TypeVariable<D extends GenericDeclaration> extends Type, AnnotatedElement {
 *  	// 类型变量对应的上边界，如果没有指定上限，返回Object 可以有多个
 *     Type[] getBounds();
 *     // 获取类型变量所在类的Type，比如TypeVariableTest<T>类，getGenericDeclaration（）得到的就是TypeVariableTest。
 *     D getGenericDeclaration();
 * 	// 获取类型变量在源码中定义的名称
 *     String getName();
 * 	// JDK8新增的，获取注解类型的上限数组
 *      AnnotatedType[] getAnnotatedBounds();
 * }
 *
 */
public class Test035_TypeParameters {
    public static void main(String[] args) {
        // typeParameters数组，表示声明的类型变量数组：[T extends Number & Serializable,R]
        TypeVariable<Class<Person>>[] typeParameters = Person.class.getTypeParameters();
        System.out.printf("类[%s]，声明的泛型变量：", Person.class.getName());
        for (TypeVariable<Class<Person>> typeVariable : typeParameters) {
            // typeVariable表示每个类型变量：T extends Number & Serializable 或 R
            // bounds表示类型变量的上限，即父类，此处表示 T extends Number & Serializable 中的Number
            Type[] bounds = typeVariable.getBounds();
            System.out.printf("[变量名：%s，上限：%s]", typeVariable.getName(), bounds[bounds.length-1]);
        }
    }

    static class Person<T extends Number & Serializable,R> {
        T a;
        R b;
        R work(T in) {
            return null;
        }
    }

    static class Student extends Person<Long, Result<Integer>> {
        @Override
        Result<Integer> work(Long in) {
            System.out.printf("work(%s)\n", in);
            return new Result<>(1);
        }
    }

    @Data
    @AllArgsConstructor
    static class Result<T> {
        private T data;
    }
}
